package edu.calpoly;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Game.java
 *
 * Created on Apr 11, 2009, 6:12:43 PM
 */

import java.util.*;

/**
 *  Not just a game but "The Game".
 */
public class Game extends GTP {

   //Setting a hardcap right now for how many moves 
   //the gobot will produce before a pass
   private int moves = 0;
   private Board board;
   //private GoBot white;
   //private GoBot black;
   private GoBot cykill;
   // list of Commands
	ArrayList<String> cmds = new ArrayList<String>(){{
		add("final_status_list");
		add("fixed_handicap");
		add("genmove");
		add("known_command");
		add("komi");
		add("list_commands");
		add("name");
		add("place_free_handicap");
		add("play");
		add("quit");
		add("set_free_handicap");
		add("showboard");
		//add("undo");
		add("boardsize");
		add("clear_board");
		add("version");
		add("final_score");
            add("depth");
            add("random");
	}};
	
   /**
   * @param args the command line arguments
   */
   public static void main(String args[]) {
	   Game endersgame = new Game();
	   Scanner sc = new Scanner(System.in);
	   
	   while (sc.hasNextLine()){
	      endersgame.parse(sc.nextLine());
	   }
	   // Not entirely sure if this will work - but seems like it's better than running the loop in the constructor.
   }

   public Game() {
	   board = new Board();
	   cykill = new GoBot(board);
	   //white = new GoBot(board, "w");
	   //black  = new GoBot(board, "b");
   }

   /**
   *  @returns Name of the engine. "GoBot"
   */
   public String name() {
      return "Gobot";
   }
   
   // for toggling random on or off for the specified color
      public String random(String cmd) {
          if(cmd.compareToIgnoreCase("w") == 0) {
             cykill.setRandom(cmd);
             return "=";
           }
           else if (cmd.compareToIgnoreCase("b") == 0){
             cykill.setRandom(cmd);
             return "=";
           }
           else{
             return "? usage : random w OR random b";
           }
       }

      // for setting the depth
      public String setDepth(String color, int depth) {
          if(depth < 1) return "? cannot set depth less than 1";
           
          if(color.compareToIgnoreCase("w") == 0) {
             cykill.setDepth(color,depth);
             return "=";
           }
           else if (color.compareToIgnoreCase("b") == 0){
             cykill.setDepth(color,depth);
             return "=";
           }
           else{
             return "? invalid color";
           }
      }

   /**
    * @returns Version of the engine. "0.1"
    */
   public String version() {
      return "2.0";
   }
   
   /**
    * The protocol makes no distinction between unknown commands and
    * known but unimplemented ones. Do not declare a command as known if it is
    * known not to work.
    *
    * @param command Name of a command
    * @returns "true" if the command is known by the engine, "false" otherwise
    */
   public String known_command(String command) {
      return null;
   }


   /**
    *  Include all known commands, including required ones and private
    *  extensions.
    *  @returns List of commands
    */
   public ArrayList<String> list_commands() {
	   return cmds;
   }
   
   /**
    * The session is terminated and the connection is closed.<br>
    * The full response of this command must be sent before the engine closes
    * the connection. The controller must receive the response before the
    * connection is closed on its side.
    */
   public void quit() {
   }
   
   /*
    * 6.3.2 Setup Commands
    */
   
   /**
    * The board size is changed. The board configuration, number of captured
    * stones, and move history become arbitrary. In GTP version 1 this command
    * also did the work of clear board. This may or may not be true for
    * implementations of GTP version 2. Thus the controller must call clear
    * board explicitly. Even if the new board size is the same as the old one,
    * the board configuration becomes arbitrary.
    *
    * @param size - New size of the board.
    * @fails Syntax error. If the engine cannot handle the new size, fails
    *          with the error message "unacceptable size".
    */
   public void boardsize(int size) {
   }
   
   /**
    * The board is cleared, the number of captured stones is reset to zero
    * for both colors and the move history is reset to empty.
    */
   public void clear_board() {
	   moves = 0;
      board.clearBoard();
   }
   
   /**
    *    Changes the komi value.
    * <br>The engine must accept the komi even if it should be ridiculous.
    *
    * @param value new value of komi.
    */
   public void komi(float value) {
   }
   
   /**
    * Handicap stones are placed on the board according to the specication
    * in section 4.1.1.
    * <br>This command is only valid if the board is empty. See section 4.1.1
    * for valid number of handicap stones. The  handicap stones are not
    * included in the move history.
    *
    * @param value Number of handicap stones.
    * @return A list of the vertices where handicap stones have been placed.
    * @fails Syntax error. invalid number of stones, board not empty
    */
   public ArrayList<String> fixed_handicap(int value) {
      return null;
   }
   
   /**
    * Handicap stones are placed on the board on the vertices the engine
    * prefers. See also section 4.1.2.
    * <br>This command is only valid if the board is empty. The engine may
    * place fewer than the requested number of stones on the board under
    * certain circumstances, as discussed in section 4.1.2. The controller can
    * check this by counting the number of vertices in the response. The
    * handicap stones are not included in the move history. Vertices must not
    * be repeated or include \pass".
    *
    * @param value Number of handicap stones.
    * @fails Syntax error, invalid number of stones, board not empty,bad
    *          vertex list
   */
   public ArrayList<String> place_free_handicap(int value) {
      return null;
   }
   
   /**
    * Handicap stones are placed on the vertices as requested.
    * This command is only valid if the board is empty. The list must have at
    * least two elements and no more than the number of board vertices minus
    * one. The engine must accept the handicap placement. The handicap stones
    * are not included in the move history. Vertices must not be repeated or
    * include \pass".
    *  
    * @param vertices A list of vertices where handicap stones should be
    *          placed on the board.
    * @fails syntax error, board not empty, bad vertex list
    */
   public void set_free_handicap(ArrayList<String> vertices) {
   }
   
   /*
    * 6.3.3 Core Play Commands
    */
   
   /**
    *  A stone of the requested color is played at the requested vertex.
    *  The number of captured stones is updated if needed and the move is
    *  added to the move history.
    *  <br>Consecutive moves of the same color are not considered illegal from
    *  the protocol point of view.
    *    
    * @param color Color of the move
    * @param vertex Vertex of the move
    * @fails syntax error, illegal move. In the latter case, fails with the
    *          error message \illegal move".
    */
   public void play(String color, String vertex) {
	   cykill.setKo(board.clone());
	   moves++;
	   if(vertex.toLowerCase().equals("pass"))
		   pass(color);
	   else
		   board.placeStone(color,vertex);	   
   }
   /**
    * Handle pass
    * @param color The color who passed.
    */
   private void pass(String color){
	   
   }
   /**
    * A stone of the requested color is played where the engine chooses. The
    * number of captured stones is updated if needed and the move is added to
    * the move history.
    * <br>Notice that \pass" is a valid vertex and should be returned if the
    * engine wants to pass. Use \resign" if you want to give up the game. The
    * controller is allowed to use this command for either color, regardless
    * who played the last move.
    *
    * @param color Color for which to generate a move.
    * @return Vertex where the move was played or the string \resign".
    */
   public String genmove(String color) {
	   /*if(color.compareToIgnoreCase("w") == 0)      
         return white.genmove();
      else return black.genmove(); */
      if(moves >= board.getBrdsize()* board.getBrdsize())
    	  return "pass";
      else
    	  moves++;
      return cykill.genmove(color); 
   }
   
   /**
    * The board conguration and the number of captured stones are reset to the
    * state before the last move. The last move is removed from the move
    * history.
    * <br>If you want to take back multiple moves, use this command multiple
    * times. The engine may fail to undo if the move history is empty or if
    * the engine only maintains a partial move history, which has been
    * exhausted by previous undos. It is never possible to undo handicap
    * placements. Use clear board if you want to start over. An engine which
    * never is able to undo should not include this command among its known
    * commands.
    *
    *    @fails If the engine is unable to take back the last move, fails with
    *          the error message "cannot undo".
    */
   public void undo() {
   }
   
   /*
    * 6.3.4 Tournament Commands
    */
   
   /**
    * If the engine never is able to determine the score, leave the command
    * unimplemented.
    *
    * @return Score as described in section 4.3.
    * @fails If the engine is unable to determine the score, fails with error
    *          message \cannot score".
    */
   public String final_score() {
      return "";
   }
   
   /**
    * See section 4.3 for details.
    * @param status Requested status.
    * @returns Stones with the requested status.
    * @fails syntax error
   */
   public ArrayList<String> final_status_list(String status) {
      return new ArrayList<String>();
   }


   /*
    * 6.3.6 Debug Commands
    */
   
   /**
    * The engine may draw the board as it likes. It is, however, required to
    * place the coordinates as described in section 2.11. This command is only
    * intended to help humans with  debugging and the output should never need
    * to be parsed   by another program.
    * @return A diagram of the board position.
    */
   public String showboard() {
      return board.toString();
   }
}


